#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import json
import re

CONFIG = {}


def init():
    global CONFIG
    CONFIG = get_config()
    os.chdir(CONFIG['root'])  # 切换到 对应 目录
    print("<Info> : 当前工作目录 [ %s ]" % CONFIG['root'])


def get_config():
    # print("尝试读取 <config.json>")
    path = "./config.json"
    try:
        with open(path, 'r', -1, 'utf-8') as f:
            local_config = json.load(f)
        # print("[ success ] 读取<config.json>成功")
        return local_config
    except json.decoder.JSONDecodeError:
        print("<Error>: 校验配置文件<config.json>json格式失败")
        print("[ tips ] 请确认sudoku.json为合法json格式")
    except UnicodeDecodeError:
        print("<Error>: 校验配置文件<config.json>编码格式失败")
        print("[ tips ] 请确认sudoku.json编码格式为utf-8")
    except IOError:
        print("<Error>: 读取配置文件<config.json>失败")
        print("[ tips ] 请重新尝试读取sudoku.json")
    return None


def get_file_type(path, debug=False):
    if os.path.isdir(path):
        if debug:
            print("<Debug>: It's a directory. %s" % path)
        return 1
    elif os.path.isfile(path):
        if debug:
            print("<Debug>: It's a normal file. %s" % path)
        return 2
    elif not os.path.exists(path):
        if debug:
            print("<Error>: It not exists! %s" % path)
        return -1
    else:
        if debug:
            print("<Error>: It's a special file(socket, FIFO, device file)!")
        return 0


def get_files(pwd=True, use_filter=False):
    files = []  # 所有的文件
    if pwd:
        files = os.listdir(CONFIG['root'])
        for index in range(len(files)):
            files[index] = os.path.join(os.getcwd(), files[index])
    else:
        for main_dir, sub_dir, file_name_list in os.walk(CONFIG['root']):
            # print("1:", main_dir)  # 当前主目录
            # print("2:", sub_dir)  # 当前主目录下的所有目录
            # print("3:", file_name_list)  # 当前主目录下的所有文件
            for filename in file_name_list:
                sub_path = os.path.join(main_dir, filename)  # 合并成一个完整路径
                ext = os.path.splitext(sub_path)[1]  # 获取文件后缀 [0]获取的是除了文件名以外的内容
                if use_filter:
                    if ext in CONFIG['filter']:
                        files.append(sub_path)
                else:
                    files.append(sub_path)
    return files


def ls(pwd=True):
    # 列出目录
    files = get_files(pwd)
    if pwd:
        for index in range(len(files)):
            _, temp_name = os.path.split(files[index])
            if get_file_type(files[index]) == 1:
                files[index] = "/ <Dir> " + temp_name
            else:
                files[index] = temp_name
        for index in range(len(files)):
            print("%s" % files[index])
    else:
        for index in range(len(files)):
            print("[%d] %s" % (index, files[index]))


def mv(src, dst):
    the_file_type = get_file_type(src)
    if the_file_type == 1:
        file_type = "file"
    elif the_file_type == 2:
        file_type = "dir"
    else:
        return
    try:
        os.rename(src, dst)
    except Exception as e:
        print(e)
        print("<Error>: Rename %s fail! %s" % (file_type, src))
    else:
        print("<Info> : Rename %s success! %s" % (file_type, dst))


def standard_match(match_string):
    print("开始标准的正则匹配...")
    pattern = r"^(\[.*\])*(.*?)(\{.*\})?$"  # pattern_example = r"^(\[.*\])*(.*?)(\{.*\})?$"
    match_obj = re.fullmatch(pattern, match_string)
    # print(match_obj.groups())
    print("Tags  = %s" % match_obj.group(1))
    print("Title = %s" % match_obj.group(2))
    print("Index = %s" % match_obj.group(3))


def replace_with_rule(origin_path, origin='default'):
    file_path, temp_filename = os.path.split(origin_path)
    file_name, file_type = os.path.splitext(temp_filename)
    new_filepath = None
    if origin == 'default':
        pass
    elif origin == 'reverse':
        # 反转字符串从最后开始匹配
        """
        """
        # matched = re.match(r'^(?P<title>.*)?\((?P<suffix>.*?)\)?$', file_name)  # 直接匹配
        # pattern_reverse = r'^(\)(?P<suffix>.*?)\()?(?P<title>.*)?$'  # 小括号
        # pattern_reverse = r'^(\](?P<suffix>.*?)\[)?(?P<title>.*)?$'  # 中括号
        # pattern_reverse = r'^(\}(?P<suffix>.*?)\{)?(?P<title>.*)?$'  # 大括号
        pattern_reverse = CONFIG['pattern']['reverse_small']
        matched = re.fullmatch(pattern_reverse, file_name[::-1])  # 反转后匹配再反转 以确保优先匹配最后一对括号
        if isinstance(matched.group('suffix'), str):
            double_reversed_filename = str.lower(matched.group('suffix').replace(" ", ""))[::-1]
            new_filename = matched['title'][::-1] + '(' + double_reversed_filename + ')'
            new_filepath = os.path.join(file_path, new_filename + file_type)
            if new_filepath == origin_path:
                new_filepath = None
    elif origin == 'add':
        # 增加指定词
        new_filepath = os.path.join(file_path, CONFIG['add'] + temp_filename)
    elif origin == 'delete':
        # 删除指定词
        if origin_path.find(CONFIG['delete']) != -1:
            new_filepath = origin_path.replace(CONFIG['delete'], "")
    elif origin == 'replace':
        # 直接替换
        if origin_path.find(CONFIG['replace']['old']) != -1:
            new_filepath = origin_path.replace(CONFIG['replace']['old'], CONFIG['replace']['new'])
    else:
        pass
    return new_filepath


def process(rule='default', debug=False):
    files = get_files(False)
    if rule == 'add':
        print("<Info> : 新增关键词 [ %s ]" % CONFIG['add'])
    elif rule == 'delete':
        print("<Info> : 删除关键词 [ %s ]" % CONFIG['delete'])
    elif rule == 'replace':
        print("<Info> : 关键词替换 [ %s ] => [ %s ]" % (CONFIG['replace']['old'], CONFIG['replace']['new']))
    for old_path in files:
        new_path = replace_with_rule(old_path, rule)
        if new_path:
            if debug:
                print("<Debug>: 新名字 %s" % new_path)
            mv(old_path, new_path)
        else:
            if debug:
                print("<Debug>: 原名字 %s 没有改动" % old_path)
            pass


def main():
    init()
    # print(CONFIG)  # 显示本地配置项
    # ls(False)  # 遍历所有文件
    ls()
    print()

    print("<Info> : 开始批量重命名文件...")
    process('reverse')
    print("<Info> : 重命名结束!")


if __name__ == "__main__":
    main()
